/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
/*
 * edit_game.cc
 * Copyright (C) jurjen 2007 <jurjen@stwerff.xs4all.nl>
 *
 * edit_game.cc is free software. You may redistribute it and/or modify it under
 * the terms of the GNU General Public License.
 */

#define DEBUG_ROUTINE "edit_game"

#include <iostream>
#include "edit_game.h"
#include "moros.h"
#include "../central/game.h"
#include "../general/log.h"
#include "game_window.h"

edit_game::edit_game(BaseObjectType* cobject, const Glib::RefPtr<Gnome::Glade::Xml> refGlade)
: Gtk::Window(cobject), glade(refGlade) {
	edit_game::present();
	glade->get_widget("name", name);
	glade->get_widget("description", description);
	glade->get_widget("join", join);
	glade->get_widget("goal", goal);
	glade->get_widget("map_name", map_name);
	glade->get_widget("game_url", game_url);
	glade->get_widget("party_list", party_list);
	glade->get_widget("cancel_game", cancel_game);
	glade->get_widget("add_party", add_party);
	glade->get_widget("create_game", create_game);
	glade->get_widget("create_label", create_label);
	glade->get_widget("game_editor", game_editor);
    glade->get_widget_derived("edit_party", party_window);
    party_window->hide();

	int colnr;
	Gtk::TreeViewColumn* col;
	Gtk::CellRendererText* renderer;

	desc_buffer=Gtk::TextBuffer::create();
	description->set_buffer(desc_buffer);
	join_store = Gtk::ListStore::create(ccols);
	join->set_model(join_store);
    int i;
    for (i=0; i<join_elms; i++) {
        Gtk::TreeModel::iterator iter = join_store->append();
        (*iter)[ccols.text] = join_types[i];
    }
    Glib::RefPtr<Gtk::TreeModel> model=join->get_model();
    join->set_active(model->children().begin());

	goal_store = Gtk::ListStore::create(ccols);
	goal->set_model(goal_store);
    for (i=0; i<goal_elms; i++) {
        Gtk::TreeModel::iterator iter = goal_store->append();
        (*iter)[ccols.text] = goal_types[i];
    }
    model=goal->get_model();
    goal->set_active(model->children().begin());

	party_store = Gtk::ListStore::create(cols);
	party_list->set_model(party_store);
	party_list->set_search_column(cols.name.index());

	renderer = Gtk::manage( new Gtk::CellRendererText() );
	colnr = party_list->append_column("Name", *renderer);
	col = party_list->get_column(colnr-1);
	col->add_attribute(renderer->property_text(), cols.name);

	renderer = Gtk::manage( new Gtk::CellRendererText() );
	colnr = party_list->append_column("Description", *renderer);
	col = party_list->get_column(colnr-1);
	col->add_attribute(renderer->property_text(), cols.description);

	cancel_game->signal_clicked().connect(sigc::mem_fun(*this, &edit_game::clicked_cancel));
	add_party->signal_clicked().connect(sigc::mem_fun(*this, &edit_game::clicked_add_party));
	create_game->signal_clicked().connect(sigc::mem_fun(*this, &edit_game::clicked_create));
	game_editor->signal_clicked().connect(sigc::mem_fun(*this, &edit_game::clicked_editor));
	party_list->signal_row_activated().connect(sigc::mem_fun(*this, &edit_game::clicked_party));
}

void edit_game::load(long gamenr) {
    if (gamenr==0) {
        create_label->set_text("Create");
    } else {
        create_label->set_text("Update");
    }
	game_nr=gamenr;
	if (games.count(gamenr)>0) {
	    Gtk::TreeModel::const_iterator it;
		game g=games[gamenr];
		name->set_text(g.name);
		desc_buffer->set_text(g.description);
		Glib::RefPtr<Gtk::TreeModel> model=join->get_model();
		Gtk::TreeModel::iterator ci=model->children().begin();
		int n;
		for (n=0; n<g.join; n++) ci++;
		join->set_active(ci);
		model=goal->get_model();
		ci=model->children().begin();
		for (n=0; n<g.goal; n++) ci++;
		goal->set_active(ci);
		map_name->set_text(g.map);
		game_url->set_text(g.url);
		party_data.clear();
		party_store->clear();
		int nr=0;
		vector<party>::iterator i;
  		for( i=g.parties.begin(); i != g.parties.end(); i++ ) {
  		    dbg_calls("Add party %s descr %s", i->name.c_str(), i->description.c_str());
			Gtk::TreeRow row = *(party_store->append());
			row[cols.name]=i->name.c_str();
			row[cols.description]=i->description.c_str();
			row[cols.party_nr]=nr++;
			party_data.push_back(*i);
		}
	}
}

void edit_game::clear_data() {
    name->set_text("");
    desc_buffer->set_text("");
    Glib::RefPtr<Gtk::TreeModel> model=join->get_model();
    join->set_active(model->children().begin());
    model=goal->get_model();
    goal->set_active(model->children().begin());
    map_name->set_text("");
    game_url->set_text("");
    party_store->clear();
}

void edit_game::save() {
	game g;
	g.name=name->get_text();
	g.description=desc_buffer->get_text();
	int i;
	Gtk::TreeModel::iterator iter = join->get_active();
	if (iter) {
		Gtk::TreeModel::Row row = *iter;
		if (row) {
			Glib::ustring val;
			row.get_value(0, val);
			for(i=0; i<join_elms; i++) {
				if (join_types[i] == val) g.join=i;
			}
		}
	}
	iter = goal->get_active();
	if (iter) {
		Gtk::TreeModel::Row row = *iter;
		if (row) {
			Glib::ustring val;
			row.get_value(0, val);
			for(i=0; i<goal_elms; i++) {
				if (goal_types[i] == val) g.goal=i;
			}
		}
	}
	g.map=map_name->get_text();
	g.url=game_url->get_text();
	g.parties.clear();
	g.owner=game_data->user;
	// get the different parties in the data
	channel *ch=game_data->cent_ch;
    ch->write("game", game_nr);
	ch->write("name", g.name);
	ch->write("descr", g.description);
	ch->write("join", g.join);
	ch->write("goal", g.goal);
	ch->write("map", g.map);
	ch->write("url", g.url);
	vector<party>::iterator pi;
	for(pi=party_data.begin(); pi!=party_data.end(); pi++) {
        ch->write("party", pi->name);
		ch->write("desc", pi->description);
        g.parties.push_back(*pi);
	}
	ch->send();
	games[game_nr]=g;
	signal_changed();
}

edit_game::~edit_game() {}

void edit_game::clicked_cancel() {
    dbg_calls("Clicked cancel");
    clear_data();
	hide();
}

void edit_game::clicked_add_party() {
    party new_party;
    party_data.push_back(new_party);
    sigc::signal<void> party_change;
    party_change.connect(sigc::mem_fun(*this, &edit_game::party_changed));
    party_window->set_party(&party_data.back(), true, party_change);
    party_window->present();
}

void edit_game::clicked_party(const Gtk::TreeModel::Path& path, Gtk::TreeViewColumn* column) {
	Glib::RefPtr<Gtk::TreeSelection> sel=party_list->get_selection();
    Gtk::TreeModel::iterator i=sel->get_selected();
    long pnr=((*i)[cols.party_nr]);
    sigc::signal<void> party_change;
    party_change.connect(sigc::mem_fun(*this, &edit_game::party_changed));
    party_window->set_party(&party_data[pnr], false, party_change);
    party_window->present();
}

void edit_game::party_changed() {
    party_store->clear();
    int nr=0;
    vector<party>::iterator i;
    for( i=party_data.begin(); i != party_data.end(); i++ ) {
        if (i->name=="") {
            i=party_data.erase(i);
        }
		Gtk::TreeRow row = *(party_store->append());
		row[cols.name]=i->name;
		row[cols.description]=i->description;
		row[cols.party_nr]=nr++;
	}
}

void edit_game::clicked_create() {
    dbg_calls("Clicked create");
	save();
	clear_data();
	hide();
}

void edit_game::session_handler(channel *ch) {
    if (ch->key=="session") {
        session=ch->value;
    }
}

void edit_game::clicked_editor() {
	communicate comm;
    sigc::signal<void, channel*> session_handler_signal;
	session="";
    session_handler_signal.connect(sigc::mem_fun(this, &edit_game::session_handler));
	channel *ch=comm.tls_client(game_data->central, AUTH_PORT, session_handler_signal);
	if (ch==0) {
		return;
	}
	ch->write("user", game_data->user);
	ch->write("password", game_data->users[game_data->user]);
	ch->write("game", "");
	ch->write("state", state_editor);
	ch->send();
	comm.complete(20);
	if (session=="") return;
	game_data->current_game=name->get_text();
	save();
	string cm="game_server -G "+name->get_text()+" -C "+game_data->central+" -S "+session+
        " -P ~/.moros/game_server -L ~/.moros/game_server.log -l 4";
	dbg_calls("System: %s", cm.c_str());
	system(cm.c_str());
    game_window *gw;
    glade->get_widget_derived("game", gw);
    gw->maximize();
    gw->present();
	clear_data();
    hide();
}
